package tc.alert.tckejisoc.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 */
public class DateUtils {

    /**
     * 默认日期格式
     */
    public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式器缓存（线程安全）
     */
    private static final ThreadLocal<SimpleDateFormat> formatterCache = ThreadLocal.withInitial(
            () -> new SimpleDateFormat(DEFAULT_PATTERN)
    );

    /**
     * 日期格式化（使用默认格式）
     *
     * @param date 日期对象
     * @return 格式化后的字符串
     */
    public static String format(Date date) {
        return formatterCache.get().format(date);
    }


    /**
     * 日期格式化（自定义格式）
     *
     * @param date    日期对象
     * @param pattern 格式模式
     * @return 格式化后的字符串
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.format(date);
    }

    /**
     * 字符串转日期（使用默认格式）
     *
     * @param dateStr 日期字符串
     * @return 日期对象
     * @throws ParseException 解析异常
     */
    public static Date parse(String dateStr) throws ParseException {
        return formatterCache.get().parse(dateStr);
    }

    /**
     * 字符串转日期（自定义格式）
     *
     * @param dateStr 日期字符串
     * @param pattern 格式模式
     * @return 日期对象
     * @throws ParseException 解析异常
     */
    public static Date parse(String dateStr, String pattern) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.parse(dateStr);
    }

    /**
     * 日期加减操作
     *
     * @param date   原始日期
     * @param field  日历字段（使用Calendar常量）
     * @param amount 加减数量
     * @return 计算后的日期
     */
    public static Date add(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    /**
     * 获取日期的开始时间（00:00:00.000）
     *
     * @param date 日期
     * @return 当天的开始时间
     */
    public static Date getStartOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取日期的结束时间（23:59:59.999）
     *
     * @param date 日期
     * @return 当天的结束时间
     */
    public static Date getEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 计算两个日期的间隔天数
     *
     * @param start 开始日期
     * @param end   结束日期
     * @return 间隔天数（正数表示end在start之后）
     */
    public static int daysBetween(Date start, Date end) {
        long time1 = start.getTime();
        long time2 = end.getTime();
        return (int) ((time2 - time1) / (1000 * 60 * 60 * 24));
    }

    /**
     * 比较两个日期的先后
     *
     * @param date1 第一个日期
     * @param date2 第二个日期
     * @return 1: date1在date2之后, -1: date1在date2之前, 0: 相等
     */
    public static int compare(Date date1, Date date2) {
        long time1 = date1.getTime();
        long time2 = date2.getTime();
        return Long.compare(time1, time2);
    }

    /**
     * 判断两个日期是否为同一天
     *
     * @param date1 第一个日期
     * @param date2 第二个日期
     * @return 是否同一天
     */
    public static boolean isSameDay(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
                && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
                && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
    }

    // 私有构造方法防止实例化
    private DateUtils() {
    }
}